home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / TOOLPAS2 / CINPUT.PAS < prev    next >
Pascal/Delphi Source File  |  1990-02-04  |  13KB  |  520 lines

  1.  
  2. (*
  3.  * Copyright 1987, 1990 Samuel H. Smith;  All rights reserved
  4.  *
  5.  * This is a component of the ProDoor System.
  6.  * Do not distribute modified versions without my permission.
  7.  * Do not remove or alter this notice or any other copyright notice.
  8.  * If you use this in your own program you must distribute source code.
  9.  * Do not use any of this in a commercial product.
  10.  *
  11.  *)
  12.  
  13. {$i prodef.inc}
  14.  
  15. {$D+}    {Global debug information}
  16. {$L+}    {Local debug information}
  17. {$DEFINE IN_CINPUT}
  18.  
  19. unit CInput;
  20.  
  21. interface
  22.  
  23.    Uses
  24.       Dos, MiniCrt, Mdosio, Tools;
  25.  
  26.    var
  27.       linenum:       integer;
  28.       pending_keys:  string;
  29.       cmdline:       string;
  30.       par:           string;
  31.       ontime:        integer;
  32.       tleft:         integer;
  33.  
  34.    const
  35.       tlimit:  integer = 10;  {default time limit}
  36.       com_chan: integer = 0;  {default to local, monitor carrier if 1 or 2}
  37.  
  38.       allow_flagging = false;
  39.       graphics = false;
  40.       red = '';
  41.       green = '';
  42.       yellow = '';
  43.       blue = '';
  44.       magenta = '';
  45.       cyan = '';
  46.       white = '';
  47.       gray = '';
  48.       fun_arcview = 'V';
  49.       fun_textview = 'T';
  50.       fun_xtract = 'X';
  51.       enter_eq = '(Enter)=';
  52.       option = '';
  53.       expert = true;
  54.       dump_user: boolean = false;
  55.  
  56.    type
  57.       user_rec = record
  58.            pagelen: integer;
  59.       end;
  60.  
  61.    const
  62.       user: user_rec = (pagelen:22);
  63.       o_logoff = 'x';
  64.       o_offok = 'x';
  65.       o_offerr = 'x';
  66.  
  67.    const
  68.       queue_size       =  300;   {fixed size of all queues}
  69.       queue_high_water =  255;   {maximum queue.count before blocking}
  70.       queue_low_water  =  100;   {unblock queue at this point}
  71.  
  72.    type
  73.       queue_rec = record
  74.          next_in:  integer;
  75.          next_out: integer;
  76.          count:    integer;
  77.          data:     array[1..queue_size] of char;
  78.       end;
  79.  
  80.    {$i intrcomm.int}
  81.  
  82.    procedure opencom(port: integer);
  83.    procedure closecom;
  84.    function local: boolean;
  85.    function carrier_present: boolean;
  86.  
  87.    procedure disp(msg:  string);
  88.    procedure newline;
  89.    procedure displn(msg:  string);
  90.    procedure space;
  91.    procedure spaces(n: integer);
  92.    procedure input(var line:  string; maxlen:    integer);
  93.    procedure prompt_def(what,options: string);
  94.    procedure get_def(what,options: string);
  95.    procedure get_cmdline_raw(len: integer);
  96.  
  97. (*******
  98.    procedure dRED(m: string);
  99.    procedure dGREEN(m: string);
  100.    procedure dYELLOW(m: string);
  101.    procedure dBLUE(m: string);
  102.    procedure dMAGENTA(m: string);
  103.    procedure dCYAN(m: string);
  104.    procedure dWHITE(m: string);
  105.    procedure dGRAY(m: string);
  106.    procedure default_color;
  107. ******)
  108.  
  109.    procedure get_cmdline;
  110.    function scan_nextpar(var cmdline: string): string;
  111.    procedure get_nextpar;
  112.  
  113.    function verify_level(fun: char): boolean;
  114.    procedure set_function(fun: char);
  115.    procedure erase_prompt(len: integer);
  116.    procedure check_time_left;
  117.    procedure display_time(left: boolean);
  118.    procedure flag_files;
  119.    procedure make_log_entry(s:string; f:boolean);
  120.    function nomore: boolean;
  121.  
  122.  
  123. (* ------------------------------------------------------------ *)
  124. implementation
  125.  
  126.    procedure flush_com;
  127.    begin
  128.       INTR_flush_com;
  129.    end;
  130.  
  131.    {$i intrcomm.inc}
  132.  
  133.    function local: boolean;
  134.    begin
  135.       local := (com_chan = 0);
  136.    end;
  137.  
  138.    procedure opencom(port: integer);
  139.    begin
  140.       com_chan := port;
  141.       if (com_chan = 1) or (com_chan = 2) then
  142.       begin
  143.          INTR_init_com(com_chan-1);
  144.          if not carrier_present then
  145.          begin
  146.             closecom;
  147.             com_chan := 0;
  148.          end;
  149.       end;
  150.    end;
  151.  
  152.    procedure closecom;
  153.    begin
  154.       if not local then
  155.          INTR_uninit_com;
  156.    end;
  157.  
  158. (*******
  159.    procedure dRED(m: string);    begin disp(RED+m); end;
  160.    procedure dGREEN(m: string);  begin disp(GREEN+m); end;
  161.    procedure dYELLOW(m: string); begin disp(YELLOW+m); end;
  162.    procedure dBLUE(m: string);   begin disp(BLUE+m); end;
  163.    procedure dMAGENTA(m: string);begin disp(MAGENTA+m); end;
  164.    procedure dCYAN(m: string);   begin disp(CYAN+m); end;
  165.    procedure dWHITE(m: string);  begin disp(WHITE+m); end;
  166.    procedure dGRAY(m: string);   begin disp(GRAY+m); end;
  167.    procedure default_color;      begin disp(GRAY); end;
  168. *******)
  169.  
  170.    (* ------------------------------------------------------------ *)
  171.    procedure get_cmdline;
  172.       (* read next command line *)
  173.    var
  174.       i: integer;
  175.  
  176.    begin
  177.       fillchar(cmdline,sizeof(cmdline),0);
  178.       input(cmdline,sizeof(cmdline)-1);
  179.       stoupper(cmdline);
  180.       newline;
  181.  
  182.       {process stacked 'ns' at end of command line}
  183.       i := pos(' NS',cmdline);
  184.       if i = 0 then
  185.          i := pos(';NS',cmdline);
  186.  
  187.       if (i > 0) and (i = length(cmdline)-2) then
  188.       begin
  189.          cmdline[0] := chr(i-1);
  190.          linenum := -30000;    {go 30000 lines before stopping again}
  191.       end;
  192.    end;
  193.  
  194.  
  195.    (* ------------------------------------------------------------ *)
  196.    function scan_nextpar(var cmdline: string): string;
  197.       (* get the next space or ';' delimited part of a command line
  198.          and return it (removing the string from the command line) *)
  199.    var
  200.       i:      integer;
  201.       par:    string;
  202.  
  203.    begin
  204.       fillchar(par,sizeof(par),0);
  205.       while copy(cmdline,1,1) = ' ' do   {remove leading spaces}
  206.          delete(cmdline,1,1);
  207.  
  208.       (* find the end of the next word *)
  209.       i := 1;
  210.       while (i <= length(cmdline)) and (cmdline[i] <> ' ') and
  211.             (cmdline[i] <> ';') and (cmdline[i] <> ',') do
  212.          inc(i);
  213.  
  214.       (* copy the word to the next param and delete it from the command line *)
  215.       par := copy(cmdline,1,i-1);
  216.       delete(cmdline,1,i);
  217.  
  218.       scan_nextpar := par;
  219.    end;
  220.  
  221.  
  222.    (* ------------------------------------------------------------ *)
  223.    procedure get_nextpar;
  224.       (* get the next space or ';' delimited part of the command line
  225.          and move it to 'par' *)
  226.    begin
  227.       fillchar(par,sizeof(par),0);
  228.       par := scan_nextpar(cmdline);
  229.    end;
  230.  
  231.  
  232.    (* ------------------------------------------------------------ *)
  233.    function carrier_present: boolean;
  234.    begin
  235.       carrier_present := (port[port_base+MSR] and MSR_RLSD) <> 0;
  236.    end;
  237.  
  238.    procedure check_carrier;
  239.    begin
  240.       if (not carrier_present) and (not dump_user) then
  241.       begin
  242.          dump_user := true;
  243.          displn(^M^J'Carrier lost!');
  244.       end;
  245.    end;
  246.  
  247.  
  248.    (* ------------------------------------------------------------ *)
  249.    procedure disp(msg:  string);
  250.    begin
  251.       write(msg);
  252.       if not local then
  253.       begin
  254.          INTR_transmit_data(msg);
  255.          check_carrier;
  256.       end;
  257.    end;
  258.  
  259.  
  260.    (* ------------------------------------------------------------ *)
  261.    procedure newline;
  262.    var
  263.       c: char;
  264.  
  265.    begin
  266. {WRITE('`1');}
  267.       verify_txque_space;
  268. {WRITE('`2');}
  269.       disp(^M^J);
  270.       inc(linenum);
  271.  
  272.       if keypressed then
  273.       begin
  274.          c := readkey;
  275.          if (c = ^K) then
  276.          begin
  277.             disable_int;
  278.             control_k;
  279.             enable_int;
  280.          end
  281.          else
  282.  
  283.          if c <> carrier_lost then
  284.          begin
  285.             inc(pending_keys[0]);
  286.             pending_keys[length(pending_keys)] := c;
  287.          end;
  288.       end;
  289.    end;
  290.  
  291.    procedure displn(msg:  string);
  292.    begin
  293.       disp(msg);
  294.       newline;
  295.    end;
  296.  
  297.    procedure dispc(c: char);
  298.    begin
  299.       disp(c);
  300.    end;
  301.  
  302.    procedure space;
  303.    begin
  304.       dispc(' ');
  305.    end;
  306.  
  307.  
  308.    (* ------------------------------------------------------------ *)
  309.    procedure spaces(n: integer);
  310.    begin
  311.       while n > 0 do
  312.       begin
  313.          space;
  314.          dec(n);
  315.       end;
  316.    end;
  317.  
  318.  
  319.    (* ------------------------------------------------------------ *)
  320.    procedure input(var line:  string;
  321.                    maxlen:    integer);
  322.    var
  323.       c:     char;
  324.  
  325.    begin
  326.       linenum := 1;
  327.       line := '';
  328.  
  329.       repeat
  330.          c := #0;
  331.  
  332.          while (c = #0) and (not dump_user) do
  333.          begin
  334.             check_time_left;
  335.  
  336.             if length(pending_keys) > 0 then
  337.             begin
  338.                c := pending_keys[1];
  339.                delete(pending_keys,1,1);
  340.             end;
  341.  
  342.             if keypressed then
  343.                c := readkey;
  344.  
  345.             if (not local) then
  346.             begin
  347.                check_carrier;
  348.                if INTR_receive_ready then
  349.                   c := INTR_receive_data;
  350.             end;
  351.  
  352.             if c = #0 then
  353.                give_up_time;
  354.          end;
  355.  
  356.          if dump_user then
  357.          begin
  358.             line := carrier_lost;
  359.             exit;
  360.          end;
  361.  
  362.          case c of
  363.             ' '..#126:
  364.                if maxlen = 0 then
  365.                begin
  366.                   line := c;
  367.                   dispc(c);
  368.                   c := ^M;    {automatic CR}
  369.                end
  370.                else
  371.  
  372.                if length(line) < maxlen then
  373.                begin
  374.                   if (wherex > 78) then
  375.                      newline;
  376.  
  377.                   line := line + c;
  378.                   dispc(c);
  379.                end;
  380.  
  381.             ^H,#127:
  382.                if length(line) > 0 then
  383.                begin
  384.                   dec(line[0]);
  385.                   disp(^H' '^H);
  386.                end;
  387.  
  388.             ^M:   ;
  389.  
  390.             ^B:   displn(wtoa(ofs(c))+'/'+ltoa(memavail));
  391.  
  392.             ^C:   dump_user := true;
  393.          end;
  394.  
  395.       until (c = ^M) or dump_user;
  396.  
  397.    end;
  398.  
  399.  
  400.    (* ------------------------------------------------------------ *)
  401.    procedure erase_prompt(len: integer);
  402.       {remove a prompt from display}
  403.    begin
  404.       dispc(^M);
  405.       spaces(len);
  406.       dispc(^M);
  407.       {default_color;}
  408.    end;
  409.  
  410.  
  411.    (* ------------------------------------------------------------ *)
  412.    procedure get_cmdline_raw(len: integer);
  413.    begin
  414.       input(cmdline,len);
  415.       stoupper(cmdline);
  416.       erase_prompt(len+length(cmdline));
  417.    end;
  418.  
  419.    procedure prompt_def(what,options: string);
  420.    begin
  421.       if not dump_user then
  422.          disp(what+' '+options);
  423.    end;
  424.  
  425.    procedure get_def(what,options: string);
  426.    begin
  427.       prompt_def(what,options);
  428.       input(cmdline,sizeof(cmdline)-1);
  429.       stoupper(cmdline);
  430.       newline;
  431.    end;
  432.  
  433.  
  434.    (* ------------------------------------------------------------ *)
  435.    procedure check_time_left;
  436.    var
  437.       time: integer;
  438.    begin
  439.       time := get_mins;
  440.       tleft := tlimit+ontime-time;
  441.  
  442.       if tleft <= 0 then
  443.       begin
  444.          displn(^M^J'Time limit exceeded!');
  445.          dump_user := true;
  446.       end;
  447.    end;
  448.  
  449.    procedure display_time;
  450.    begin
  451.       check_time_left;
  452.       disp('('+itoa(tleft)+' left) ');
  453.    end;
  454.  
  455.  
  456.    (* ------------------------------------------------------------------- *)
  457.    function nomore: boolean;
  458.       {check for more output to user; returns true if user doesn't want more}
  459.    begin
  460.       check_time_left;
  461.       if dump_user or (linenum >= 2000) then
  462.       begin
  463.          nomore := true;
  464.          exit;
  465.       end;
  466.  
  467.       nomore := false;
  468.       if linenum < user.pagelen then
  469.          exit;
  470.  
  471.       {preserve command-line context since the following code "pops up" over
  472.        what ever is running in the foreground}
  473.  
  474.       display_time(false);
  475.       prompt_def('More:','(Enter) or (Y)es, (N)o, (NS)non-stop? ');
  476.       get_cmdline_raw(56);
  477.       linenum := 1;
  478.  
  479.       get_nextpar;
  480.       if (par[1] = 'N') or dump_user then
  481.       begin
  482.          if par[2] = 'S' then
  483.             linenum := -30000     {go 30000 lines before stopping again}
  484.          else
  485.          begin
  486.             nomore := true;
  487.             linenum := 2000;   {flag that nomore is in effect}
  488.          end;
  489.       end;
  490.    end;
  491.  
  492.  
  493.    (* ------------------------------------------------------------ *)
  494.    procedure make_log_entry(s:string; f:boolean);
  495.    begin
  496.       if f then displn(s);
  497.    end;
  498.  
  499.    function verify_level(fun: char): boolean;
  500.    begin
  501.       verify_level := true;
  502.    end;
  503.  
  504.    procedure set_function(fun: char);
  505.    begin
  506.    end;
  507.  
  508.    procedure flag_files;
  509.    begin
  510.    end;
  511.  
  512.  
  513. begin
  514.    fillchar(rxque,sizeof(rxque),0);
  515.    fillchar(txque,sizeof(txque),0);
  516.    ontime := get_mins;
  517.    pending_keys := '';
  518. end.
  519.  
  520.